import { Scalar as b } from '../nodes/Scalar.js';
import {
  foldFlowLines as E,
  FOLD_QUOTED as U,
  FOLD_FLOW as N,
  FOLD_BLOCK as A,
} from './foldFlowLines.js';
const D = (s, e) => ({
    indentAtStart: e ? s.indent.length : s.indentAtStart,
    lineWidth: s.options.lineWidth,
    minContentWidth: s.options.minContentWidth,
  }),
  F = s => /^(%|---|\.\.\.)/m.test(s);
function I(s, e, n) {
  if (!e || e < 0) return !1;
  const l = e - n,
    u = s.length;
  if (u <= l) return !1;
  for (let r = 0, t = 0; r < u; ++r)
    if (
      s[r] ===
      `
`
    ) {
      if (r - t > l) return !0;
      if (((t = r + 1), u - t <= l)) return !1;
    }
  return !0;
}
function S(s, e) {
  const n = JSON.stringify(s);
  if (e.options.doubleQuotedAsJSON) return n;
  const { implicitKey: l } = e,
    u = e.options.doubleQuotedMinMultiLineLength,
    r = e.indent || (F(s) ? '  ' : '');
  let t = '',
    f = 0;
  for (let i = 0, o = n[i]; o; o = n[++i])
    if (
      (o === ' ' &&
        n[i + 1] === '\\' &&
        n[i + 2] === 'n' &&
        ((t += n.slice(f, i) + '\\ '), (i += 1), (f = i), (o = '\\')),
      o === '\\')
    )
      switch (n[i + 1]) {
        case 'u':
          {
            t += n.slice(f, i);
            const a = n.substr(i + 2, 4);
            switch (a) {
              case '0000':
                t += '\\0';
                break;
              case '0007':
                t += '\\a';
                break;
              case '000b':
                t += '\\v';
                break;
              case '001b':
                t += '\\e';
                break;
              case '0085':
                t += '\\N';
                break;
              case '00a0':
                t += '\\_';
                break;
              case '2028':
                t += '\\L';
                break;
              case '2029':
                t += '\\P';
                break;
              default:
                a.substr(0, 2) === '00'
                  ? (t += '\\x' + a.substr(2))
                  : (t += n.substr(i, 6));
            }
            (i += 5), (f = i + 1);
          }
          break;
        case 'n':
          if (l || n[i + 2] === '"' || n.length < u) i += 1;
          else {
            for (
              t +=
                n.slice(f, i) +
                `

`;
              n[i + 2] === '\\' && n[i + 3] === 'n' && n[i + 4] !== '"';

            )
              (t += `
`),
                (i += 2);
            (t += r), n[i + 2] === ' ' && (t += '\\'), (i += 1), (f = i + 1);
          }
          break;
        default:
          i += 1;
      }
  return (t = f ? t + n.slice(f) : n), l ? t : E(t, r, U, D(e, !1));
}
function w(s, e) {
  if (
    e.options.singleQuote === !1 ||
    (e.implicitKey &&
      s.includes(`
`)) ||
    /[ \t]\n|\n[ \t]/.test(s)
  )
    return S(s, e);
  const n = e.indent || (F(s) ? '  ' : ''),
    l =
      "'" +
      s.replace(/'/g, "''").replace(
        /\n+/g,
        `$&
${n}`,
      ) +
      "'";
  return e.implicitKey ? l : E(l, n, N, D(e, !1));
}
function O(s, e) {
  const { singleQuote: n } = e.options;
  let l;
  if (n === !1) l = S;
  else {
    const u = s.includes('"'),
      r = s.includes("'");
    u && !r ? (l = w) : r && !u ? (l = S) : (l = n ? w : S);
  }
  return l(s, e);
}
let B;
try {
  B = new RegExp(
    `(^|(?<!
))
+(?!
|$)`,
    'g',
  );
} catch {
  B = /\n+(?!\n|$)/g;
}
function y({ comment: s, type: e, value: n }, l, u, r) {
  const { blockQuote: t, commentString: f, lineWidth: i } = l.options;
  if (!t || /\n[\t ]+$/.test(n) || /^\s*$/.test(n)) return O(n, l);
  const o = l.indent || (l.forceBlockIndent || F(n) ? '  ' : ''),
    a =
      t === 'literal'
        ? !0
        : t === 'folded' || e === b.BLOCK_FOLDED
          ? !1
          : e === b.BLOCK_LITERAL
            ? !0
            : !I(n, i, o.length);
  if (!n)
    return a
      ? `|
`
      : `>
`;
  let g, d;
  for (d = n.length; d > 0; --d) {
    const h = n[d - 1];
    if (
      h !==
        `
` &&
      h !== '	' &&
      h !== ' '
    )
      break;
  }
  let c = n.substring(d);
  const k = c.indexOf(`
`);
  k === -1
    ? (g = '-')
    : n === c || k !== c.length - 1
      ? ((g = '+'), r && r())
      : (g = ''),
    c &&
      ((n = n.slice(0, -c.length)),
      c[c.length - 1] ===
        `
` && (c = c.slice(0, -1)),
      (c = c.replace(B, `$&${o}`)));
  let p = !1,
    $,
    _ = -1;
  for ($ = 0; $ < n.length; ++$) {
    const h = n[$];
    if (h === ' ') p = !0;
    else if (
      h ===
      `
`
    )
      _ = $;
    else break;
  }
  let L = n.substring(0, _ < $ ? _ + 1 : $);
  L && ((n = n.substring(L.length)), (L = L.replace(/\n+/g, `$&${o}`)));
  let Q = (a ? '|' : '>') + (p ? (o ? '2' : '1') : '') + g;
  if ((s && ((Q += ' ' + f(s.replace(/ ?[\r\n]+/g, ' '))), u && u()), a))
    return (
      (n = n.replace(/\n+/g, `$&${o}`)),
      `${Q}
${o}${L}${n}${c}`
    );
  n = n
    .replace(
      /\n+/g,
      `
$&`,
    )
    .replace(/(?:^|\n)([\t ].*)(?:([\n\t ]*)\n(?![\n\t ]))?/g, '$1$2')
    .replace(/\n+/g, `$&${o}`);
  const T = E(`${L}${n}${c}`, o, A, D(l, !0));
  return `${Q}
${o}${T}`;
}
function K(s, e, n, l) {
  const { type: u, value: r } = s,
    {
      actualString: t,
      implicitKey: f,
      indent: i,
      indentStep: o,
      inFlow: a,
    } = e;
  if (
    (f &&
      r.includes(`
`)) ||
    (a && /[[\]{},]/.test(r))
  )
    return O(r, e);
  if (
    !r ||
    /^[\n\t ,[\]{}#&*!|>'"%@`]|^[?-]$|^[?-][ \t]|[\n:][ \t]|[ \t]\n|[\n\t ]#|[\n\t :]$/.test(
      r,
    )
  )
    return f ||
      a ||
      !r.includes(`
`)
      ? O(r, e)
      : y(s, e, n, l);
  if (
    !f &&
    !a &&
    u !== b.PLAIN &&
    r.includes(`
`)
  )
    return y(s, e, n, l);
  if (F(r)) {
    if (i === '') return (e.forceBlockIndent = !0), y(s, e, n, l);
    if (f && i === o) return O(r, e);
  }
  const g = r.replace(
    /\n+/g,
    `$&
${i}`,
  );
  if (t) {
    const d = p => {
        var $;
        return (
          p.default &&
          p.tag !== 'tag:yaml.org,2002:str' &&
          (($ = p.test) == null ? void 0 : $.test(g))
        );
      },
      { compat: c, tags: k } = e.doc.schema;
    if (k.some(d) || (c != null && c.some(d))) return O(r, e);
  }
  return f ? g : E(g, i, N, D(e, !1));
}
function R(s, e, n, l) {
  const { implicitKey: u, inFlow: r } = e,
    t =
      typeof s.value == 'string'
        ? s
        : Object.assign({}, s, { value: String(s.value) });
  let { type: f } = s;
  f !== b.QUOTE_DOUBLE &&
    /[\x00-\x08\x0b-\x1f\x7f-\x9f\u{D800}-\u{DFFF}]/u.test(t.value) &&
    (f = b.QUOTE_DOUBLE);
  const i = a => {
    switch (a) {
      case b.BLOCK_FOLDED:
      case b.BLOCK_LITERAL:
        return u || r ? O(t.value, e) : y(t, e, n, l);
      case b.QUOTE_DOUBLE:
        return S(t.value, e);
      case b.QUOTE_SINGLE:
        return w(t.value, e);
      case b.PLAIN:
        return K(t, e, n, l);
      default:
        return null;
    }
  };
  let o = i(f);
  if (o === null) {
    const { defaultKeyType: a, defaultStringType: g } = e.options,
      d = (u && a) || g;
    if (((o = i(d)), o === null))
      throw new Error(`Unsupported default string type ${d}`);
  }
  return o;
}
export { R as stringifyString };
